/*
 * direccionamiento.c
 *
 *  Created on: 23/09/2011
 *      Author: alejandro
 */
#include "abriryleer.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <stdint.h>
#include <sys/socket.h>
#include "socket.h"
#include <semaphore.h>


#define FILEPATH "/home/alejandro/small_fat32.disk"

extern conexion *poolDeConexiones;
extern sem_t poolSemaforo;
extern sem_t poolMutex;

/*char* mandarALeerBloque(uint32_t numeroDeBloque){
	int DescriptorArchivo;
	char *bloque=malloc(1024);
	struct stat estado_arch;
	DescriptorArchivo = abrirArchivo(FILEPATH, &estado_arch);
	memcpy(bloque, leerSector(numeroDeBloque * 2, estado_arch, DescriptorArchivo), 512);
	memcpy(bloque + 512, leerSector((numeroDeBloque * 2) + 1, estado_arch, DescriptorArchivo), 512);
	close(DescriptorArchivo);
	return bloque;
}*/

/*void mandarAEscribirBloque(uint32_t numeroDeBloque, char* bloque){
	int DescriptorArchivo;
	struct stat estado_arch;
	DescriptorArchivo = abrirArchivo(FILEPATH, &estado_arch);
	escribirSector(numeroDeBloque * 2, DescriptorArchivo, estado_arch, bloque, 512);
	escribirSector((numeroDeBloque * 2) + 1, DescriptorArchivo, estado_arch, bloque + 512, 512);
	close(DescriptorArchivo);
}*/

void armarPaqueteParaLeer(uint32_t numeroDeSector, paquete *NIPC){
	NIPC->type=leer;
	NIPC->nroSector=numeroDeSector;
	NIPC->payload_Length=0;
	memset(NIPC->payload,'\0',512);
}

void armarPaqueteParaEscribir(uint32_t numeroDeSector, char *sector, paquete *NIPC){
	NIPC->type=escribir;
	NIPC->nroSector=numeroDeSector;
	NIPC->payload_Length=512;
	memcpy(NIPC->payload, sector, 512);
}

char* mandarALeerBloque(uint32_t numeroDeBloque){
	char *bloque=malloc(1024);
	int posicionSocket;
	sem_wait(&poolSemaforo);
	sem_wait(&poolMutex);
	posicionSocket = buscarConexionDisponible();
	sem_post(&poolMutex);
	paquete* NIPC=malloc(sizeof(paquete));
	armarPaqueteParaLeer(numeroDeBloque*2,NIPC);
	int enviados=0;
	enviados= send(poolDeConexiones[posicionSocket].socket, NIPC,sizeof(paquete),0);
	if(enviados==-1 || enviados!= sizeof(paquete))
		perror("send");

	NIPC->nroSector++;
	enviados= send(poolDeConexiones[posicionSocket].socket, NIPC, sizeof(paquete), 0);
	if(enviados==-1 || enviados!= sizeof(paquete))
		perror("send");

	recv(poolDeConexiones[posicionSocket].socket, NIPC, sizeof(paquete), MSG_WAITALL);
	if(NIPC->nroSector==numeroDeBloque*2)
		memcpy(bloque, NIPC->payload, 512);
	else
		memcpy(bloque + 512, NIPC->payload, 512);

	recv(poolDeConexiones[posicionSocket].socket, NIPC, sizeof(paquete), MSG_WAITALL);
	if(NIPC->nroSector==numeroDeBloque*2)
		memcpy(bloque, NIPC->payload, 512);
	else
		memcpy(bloque + 512, NIPC->payload, 512);

	poolDeConexiones[posicionSocket].estado = disponible;
	sem_post(&poolSemaforo);
	free(NIPC);
	return bloque;
}

void mandarAEscribirBloque(uint32_t numeroDeBloque, char *bloque){
	int posicionSocket;
	sem_wait(&poolSemaforo);
	sem_wait(&poolMutex);
	posicionSocket = buscarConexionDisponible();
	sem_post(&poolMutex);
	paquete* NIPC = (paquete*)malloc(sizeof(paquete));
	armarPaqueteParaEscribir(numeroDeBloque * 2, bloque, NIPC);
	send(poolDeConexiones[posicionSocket].socket, NIPC, sizeof(paquete), 0);
	armarPaqueteParaEscribir((numeroDeBloque * 2) + 1, bloque + 512, NIPC);
	send(poolDeConexiones[posicionSocket].socket, NIPC,sizeof(paquete), 0);
	recv(poolDeConexiones[posicionSocket].socket, NIPC,sizeof(paquete), MSG_WAITALL);
	recv(poolDeConexiones[posicionSocket].socket, NIPC,sizeof(paquete), MSG_WAITALL);
	poolDeConexiones[posicionSocket].estado=disponible;
	sem_post(&poolSemaforo);
	free(NIPC);
}
